package com.shop.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.query.MPJQueryWrapper;
import com.shop.admin.service.IPaperService;
import com.shop.admin.validate.commons.PageValidate;
import com.shop.admin.validate.paper.*;
import com.shop.admin.vo.paper.PaperCourseVo;
import com.shop.admin.vo.paper.PaperDetailVo;
import com.shop.admin.vo.paper.PaperListedVo;
import com.shop.admin.vo.paper.PaperQuestionVo;
import com.shop.common.config.GlobalConfig;
import com.shop.common.core.PageResult;
import com.shop.common.entity.paper.Paper;
import com.shop.common.entity.paper.PaperCourse;
import com.shop.common.entity.paper.PaperQuestion;
import com.shop.common.mapper.paper.PaperCourseMapper;
import com.shop.common.mapper.paper.PaperLogMapper;
import com.shop.common.mapper.paper.PaperMapper;
import com.shop.common.mapper.paper.PaperQuestionMapper;
import com.shop.common.util.TimeUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;

/**
 * 考卷库实现类
 * @author DragonDean
 */
@Service
public class PaperServiceImpl implements IPaperService {
        
    @Resource
    PaperMapper paperMapper;

    @Resource
    PaperQuestionMapper paperQuestionMapper;

    @Resource
    PaperCourseMapper paperCourseMapper;

    @Resource
    PaperLogMapper paperLogMapper;



    /**
     * 考卷库列表
     *
     * @author DragonDean
     * @param pageValidate 分页参数
     * @param searchValidate 搜索参数
     * @return PageResult<PaperListedVo>
     */
    @Override
    public PageResult<PaperListedVo> list(PageValidate pageValidate, PaperSearchValidate searchValidate) {
        Integer page  = pageValidate.getPageNo();
        Integer limit = pageValidate.getPageSize();

        QueryWrapper<Paper> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);
        queryWrapper.orderByDesc("id");

        paperMapper.setSearch(queryWrapper, searchValidate, new String[]{
            "=:code:str",
            "like:title:str",
            "=:isPublic@is_public:int",
            "=:intro:str",
            "=:passingMark@passing_mark:int",
            "=:status:int",
        });

        IPage<Paper> iPage = paperMapper.selectPage(new Page<>(page, limit), queryWrapper);

        List<PaperListedVo> list = new LinkedList<>();
        for(Paper item : iPage.getRecords()) {
            PaperListedVo vo = new PaperListedVo();
            BeanUtils.copyProperties(item, vo);
            vo.setCreateTime(TimeUtils.timestampToDate(item.getCreateTime()));
            vo.setUpdateTime(TimeUtils.timestampToDate(item.getUpdateTime()));
            list.add(vo);
        }

        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
    }

    /**
     * 考卷库详情
     *
     * @author DragonDean
     * @param id 主键参数
     * @return Paper
     */
    @Override
    public PaperDetailVo detail(Integer id) {
        Paper model = paperMapper.selectOne(
                new QueryWrapper<Paper>()
                    .eq("id", id)
                    .eq("is_delete", 0)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在");

        PaperDetailVo vo = new PaperDetailVo();
        BeanUtils.copyProperties(model, vo);

        // 查询试题
        MPJQueryWrapper<PaperQuestionVo> queryWrapper = new MPJQueryWrapper<>();
        queryWrapper.select("q.id,q.title,q.type,q.options,q.keywords,q.explanation,t.score");
        queryWrapper.eq("paper_id", model.getId());
        queryWrapper.eq("t.is_delete", 0);
        queryWrapper.orderByDesc("t.id");
        queryWrapper.innerJoin("?_question q on q.id = t.question_id".replace("?_", GlobalConfig.tablePrefix));

        List<PaperQuestionVo> questionVos = paperQuestionMapper.selectJoinList(PaperQuestionVo.class, queryWrapper);
        vo.setQuestions(questionVos);

        // 查询课程
        List<PaperCourse> paperCourses = paperCourseMapper.selectList(
                new QueryWrapper<PaperCourse>()
                    .eq("paper_id", model.getId())
                    .eq("is_delete", 0)
                    .orderByDesc("id"));
        List<Integer> courseIds = paperCourses.stream().map(PaperCourse::getCourseId).toList();
        if(!courseIds.isEmpty()){
            List<PaperCourseVo> paperCoursesVos = new LinkedList<>();
            for(PaperCourse item : paperCourses) {
                PaperCourseVo paperCourseVo = new PaperCourseVo();
                paperCourseVo.setId(item.getCourseId());
                paperCourseVo.setTitle(item.getTitle());
                paperCoursesVos.add(paperCourseVo);
            }
            vo.setCourses(paperCoursesVos);
        }

        return vo;
    }

    /**
     * 考卷库新增
     *
     * @author DragonDean
     * @param createValidate 参数
     */
    @Override
    public void add(PaperCreateValidate createValidate) {
        // 编号排重
        Paper modelCode = paperMapper.selectOne(
                new QueryWrapper<Paper>()
                    .eq("code", createValidate.getCode())
                    .eq("is_delete", 0)
                    .last("limit 1"));
        Assert.isNull(modelCode, "编号已存在!");

        Paper model = new Paper();
        model.setCode(createValidate.getCode());
        model.setTitle(createValidate.getTitle());
        model.setIsPublic(createValidate.getIsPublic());
        model.setIntro(createValidate.getIntro());
        model.setPassingMark(createValidate.getPassingMark());
        model.setTime(createValidate.getTime());
        model.setCredit(createValidate.getCredit());
        model.setStatus(createValidate.getStatus());
        model.setCreateTime(System.currentTimeMillis() / 1000);
        model.setUpdateTime(System.currentTimeMillis() / 1000);
        paperMapper.insert(model);

        // 如果有提交试题，则添加试题
        if (createValidate.getQuestions() != null && !createValidate.getQuestions().isEmpty()) {
            _setPaperQuestion(model, createValidate.getQuestions());
        }

        // 如果有提交课程，则添加课程
        if (createValidate.getCourses() != null && !createValidate.getCourses().isEmpty()) {
            _setPaperCourse(model, createValidate.getCourses());
        }
    }

    /**
     * 考卷库编辑
     *
     * @author DragonDean
     * @param updateValidate 参数
     */
    @Override
    public void edit(PaperUpdateValidate updateValidate) {
        Paper model = paperMapper.selectOne(
                new QueryWrapper<Paper>()
                    .eq("id",  updateValidate.getId())
                    .eq("is_delete", 0)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在!");
        // 编号排重
        if(!model.getCode().equals(updateValidate.getCode())){
            Paper modelCode = paperMapper.selectOne(
                    new QueryWrapper<Paper>()
                        .eq("code", updateValidate.getCode())
                        .eq("is_delete", 0)
                        .last("limit 1"));
            Assert.isNull(modelCode, "编号已存在!");
        }

        model.setCode(updateValidate.getCode());
        model.setTitle(updateValidate.getTitle());
        model.setIsPublic(updateValidate.getIsPublic());
        model.setIntro(updateValidate.getIntro());
        model.setPassingMark(updateValidate.getPassingMark());
        model.setTime(updateValidate.getTime());
        model.setCredit(updateValidate.getCredit());
        model.setStatus(updateValidate.getStatus());
        model.setUpdateTime(System.currentTimeMillis() / 1000);
        paperMapper.updateById(model);

        _setPaperQuestion(model, updateValidate.getQuestions());

        _setPaperCourse(model, updateValidate.getCourses());
    }

    /**
     * 修改状态（启用或者禁用）
     */
    @Override
    public void setStatus(Integer id, Integer status) {
        Paper model = paperMapper.selectOne(
                new QueryWrapper<Paper>()
                    .eq("id", id)
                    .eq("is_delete", 0)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在!");

        model.setStatus(status);
        model.setUpdateTime(System.currentTimeMillis() / 1000);
        paperMapper.updateById(model);
    }


    /**
     * 考卷库删除
     *
     * @author DragonDean
     * @param id 主键ID
     */
    @Override
    public void del(Integer id) {
        Paper model = paperMapper.selectOne(
                new QueryWrapper<Paper>()
                    .eq("id", id)
                    .eq("is_delete", 0)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在!");

        model.setIsDelete(1);
        model.setDeleteTime(System.currentTimeMillis() / 1000);
        paperMapper.updateById(model);
    }

    /**
     *  设置一个试卷的题库
     */
    private void _setPaperQuestion(Paper paper, List<PaperQuestionValidate> questions){
        // 先软删除原有的题库
        PaperQuestion delModel = new PaperQuestion();
        delModel.setIsDelete(1);
        delModel.setDeleteTime(System.currentTimeMillis() / 1000);
        paperQuestionMapper.update(delModel, new QueryWrapper<PaperQuestion>().eq("paper_id", paper.getId()));

        // 添加新的题库
        Integer totalScore = 0;
        for(PaperQuestionValidate item : questions) {
            PaperQuestion paperQuestion = new PaperQuestion();
            paperQuestion.setPaperId(paper.getId());
            paperQuestion.setQuestionId(item.getId());
            paperQuestion.setScore(item.getScore());
            paperQuestion.setCreateTime(System.currentTimeMillis() / 1000);
            paperQuestionMapper.insert(paperQuestion);
            totalScore += item.getScore();
        }
        paper.setScore(totalScore);
        paperMapper.updateById(paper);
    }

    /**
     * 设置试卷的关联课程
     */
    private void _setPaperCourse(Paper paper, List<PaperCourseValidate> courses) {
        // 先删除原有的关联课程
        PaperCourse delModel = new PaperCourse();
        delModel.setIsDelete(1);
        delModel.setDeleteTime(System.currentTimeMillis() / 1000);
        paperCourseMapper.update(delModel, new QueryWrapper<PaperCourse>().eq("paper_id", paper.getId()));

        // 添加新的关联课程
        for(PaperCourseValidate item : courses) {
            PaperCourse paperCourse = new PaperCourse();
            paperCourse.setPaperId(paper.getId());
            paperCourse.setCourseId(item.getId());
            paperCourse.setTitle(item.getTitle());
            paperCourse.setCreateTime(System.currentTimeMillis() / 1000);
            paperCourseMapper.insert(paperCourse);
        }
    }

}
